Correlation of discrete signals

Correlation is a measurement of how similar two signals. The cross correlation allows us to measure the similiarity between two signals at different lag positions.


In [1]:
# Sin function to generate signals
delay = 0.6 # ms

f = lambda(x) : np.sin(x) # original signal
g = lambda(x) : np.sin(x - delay) # introduce s delay

In [2]:
dt = 0.05 # sampling interval (in ms)
# to get a good estimation of the delay with cross correlation, you need many perdiods.
time = np.arange(start = 0, stop =30.00, step = dt) # sample 5 ms seconds at 20 kHz (100 samples)

# generate signals
A, B = f(time), g(time)

# Plot signals
plt.plot(time, A, lw=1, color = 'magenta');
plt.plot(time, B, lw=1, color = 'blue');
plt.xlabel('Time (ms)');
plt.ylabel('Signal (AU)');



In [3]:
# compute signal autocorrelation

coor = np.correlate(A, A, 'same')
maxlag = int(coor.size/2)

lag = np.arange(-maxlag, maxlag+coor.size%2)*dt

plt.plot(lag, coor, lw=1);
line = plt.axvline(x=0, ymin=-40, ymax = 50, linewidth=1.5, color='r')
line.set_dashes([8, 4, 2, 4, 2, 4])



In [4]:
# compute cross correlation

coor = np.correlate(A, B, 'same')
maxlag = int(coor.size/2) 
lag = np.arange(-maxlag, maxlag + coor.size%2 )*dt

# plot cross correlogram with line in delay
plt.plot(lag, coor, lw=1);
line = plt.axvline(x=-delay, ymin=np.min(coor), ymax = np.max(coor), linewidth=1.5, color='r')
line.set_dashes([8, 4, 2, 4, 2, 4])



In [5]:
# Calculate lag position of maximal correlation
def lag_ix(x,y):

    corr = np.correlate(x,y,mode='full')
    pos_ix = np.argmax( np.abs(corr) )
    lag_ix = pos_ix - (corr.size-1)/2
    return lag_ix

lag_ix(A,B)


Out[5]:
-11

In [6]:
delay_estimation = -lag_ix(A,B)*dt # in ms
delay_estimation


Out[6]:
0.55000000000000004

In [7]:
plt.plot(lag, coor, lw=1);
line = plt.axvline(x=-delay_estimation, ymin=-40, ymax = 50,
                   linewidth=1.5, color='r', label='estimated delay')
line = plt.axvline(x=-delay, ymin=np.min(coor), ymax = np.max(coor),
                   linewidth=1.5, color='c', label='true delay')

line.set_dashes([8, 4, 2, 4, 2, 4]) 
plt.xlim(-1.5*delay, 0)

plt.legend(loc='lower right');



In [7]: